package com.sc.nft.dao;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.nft.entity.dto.SearchExistListDTO;
import com.sc.nft.entity.dto.SearchStartAndStopDTO;
import com.sc.nft.entity.vo.SearchExistListVO;
import com.sc.nft.entity.vo.SearchListVO;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.mapper.SearchMapper;
import com.sc.nft.entity.Search;
import com.sc.nft.service.SearchService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 搜索配置(Search)表Dao层
 *
 * @author 王伟成
 * @since 2024-03-05 14:07:14
 */
@Slf4j
@Repository
public class SearchDao extends ServiceImpl<SearchMapper, Search> {
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 展示列表
     * 功能使用缓存进行处理,任何更改全部触发缓存更新
     *
     * @return SearchListVO
     */
    public List<SearchListVO> displayList() {
        // 如果缓存里面有的话直接从缓存里面获取 不在从数据库里面拿
        String key = RedisKeyEnum.SEARCH.getKey();
        Boolean exist = redisTemplate.hasKey(key);
        if (exist) {
            return JSONObject.parseArray(Convert.toStr(redisTemplate.opsForValue().get(key)), SearchListVO.class);
        }
        // 从数据库里面拿数据
        LambdaQueryWrapper<Search> searchLambdaQueryWrapper = Wrappers.lambdaQuery();
        searchLambdaQueryWrapper.eq(Search::getType, 1);
        searchLambdaQueryWrapper.eq(Search::getStatus, Boolean.TRUE);
        searchLambdaQueryWrapper.orderByDesc(Search::getSort);
        searchLambdaQueryWrapper.orderByDesc(Search::getId);
        List<Search> list = list(searchLambdaQueryWrapper);
        if (CollUtil.isEmpty(list)) {
            return null;
        }
        List<SearchListVO> result = BeanUtil.copyToList(list, SearchListVO.class);
        redisTemplate.opsForValue().set(key, JSONObject.toJSONString(result),30, TimeUnit.MINUTES);
        return result;
    }


    public IPage<SearchExistListVO> existList(SearchExistListDTO searchExistListDTO) {
        LambdaQueryWrapper<Search> existListQueryWrapper = Wrappers.lambdaQuery();
        existListQueryWrapper.like(StrUtil.isNotBlank(searchExistListDTO.getSearchTitle()),Search::getSearchTitle,searchExistListDTO.getSearchTitle());
        existListQueryWrapper.eq(searchExistListDTO.getStatus()!=null,Search::getStatus,searchExistListDTO.getStatus());
        existListQueryWrapper.orderByDesc(Search::getSort);
        existListQueryWrapper.orderByDesc(Search::getId);
        Page<Search> page = page(searchExistListDTO.toMp(), existListQueryWrapper);
        return page.convert(search -> {
            SearchExistListVO searchExistListVO = new SearchExistListVO();
            searchExistListVO.setId(search.getId());
            searchExistListVO.setSearchTitle(search.getSearchTitle());
            searchExistListVO.setStatus(search.getStatus());
            searchExistListVO.setSort(search.getSort());
            searchExistListVO.setCreateTime(search.getCreateTime());
            return searchExistListVO;
        });
    }


    public void insert(Search search){
        search.insert();
        // 刷新缓存
        cacheFlipFlop();
    }



    /**
     *缓存触发器,所有的任何更新全部触发这个缓存触发器.这个触发器用来干掉所有关联的缓存.
     */
    public void cacheFlipFlop(){
        redisTemplate.delete(RedisKeyEnum.SEARCH.getKey());
    }

    public void edit(Search search) {
        search.updateById();
        // 刷新缓存
        cacheFlipFlop();
    }
    public void startAndStop(SearchStartAndStopDTO searchStartAndStopDTO) {
        LambdaUpdateWrapper<Search> searchLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        searchLambdaUpdateWrapper.eq(Search::getId,searchStartAndStopDTO.getId());
        searchLambdaUpdateWrapper.set(Search::getStatus,searchStartAndStopDTO.getStatus());
        update(searchLambdaUpdateWrapper);
        // 刷新缓存
        cacheFlipFlop();
    }

}
